package com.group.project.hrms.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.group.project.hrms.entity.ContactBasic;
import com.group.project.hrms.entity.DingLeaveRecord;
import com.group.project.hrms.entity.DingResultEntity.DingAdminEntity;
import com.group.project.hrms.entity.DingVacationType;
import com.group.project.hrms.entity.ResultEntity.ResultEntity;
import com.group.project.hrms.service.IContactBasicService;
import com.group.project.hrms.service.IDingLeaveRecordService;
import com.group.project.hrms.service.IDingVacationTypeService;
import com.group.project.hrms.utils.BasicInfoUtil;
import com.group.project.hrms.utils.DingAccessUtils;
import com.group.project.hrms.utils.LogUtil;
import com.group.project.hrms.utils.ProgressUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
public class DingLeaveRecordController {

    @Autowired
    private IContactBasicService iContactBasicService;

    @Autowired
    private IDingLeaveRecordService iDingLeaveRecordService;

    @Autowired
    private DingAccessUtils dingAccessUtils;

    @Autowired
    private IDingVacationTypeService iDingVacationTypeService;

    @Autowired
    private BasicInfoUtil basicInfoUtil;

    @Autowired
    private LogUtil logUtil;


    /**
     * 该方法将为前端考勤审批页面初始化所需数据
     * @param request http请求
     * @return 标准返回值对象
     */
    @RequestMapping("/basic/getApprovalPageData")
    @ResponseBody
    public ResultEntity getApprovalPageData(HttpServletRequest request){
        ResultEntity resultEntity = new ResultEntity();
        List<Map> resultList = new ArrayList<>();
        try{
            Map<String, Object> map = new HashMap<>();
            map.put("contacts", iContactBasicService.selectAllContactBasic());
            map.put("vacationType", iDingVacationTypeService.selectAllDingVacationType());
            resultList.add(map);
            resultEntity.setCode("S");
            resultEntity.setMsg("Success");
            resultEntity.setDataList(resultList);
            return resultEntity;
        }catch (Exception e){
            e.printStackTrace();
        }
        resultEntity.setCode("F");
        resultEntity.setMsg("初始化数据失败");
        return resultEntity;
    }


    /**
     * 该方法将接收用户传入的指定月份，从钉钉中同步考勤单据到本地数据库
     * @param map 用户传入的月份
     * @param request http请求
     * @return 标准返回值结果
     */
    @RequestMapping("/basic/doSyncLeaveStatusFromDing")
    @ResponseBody
    public ResultEntity doSyncLeaveStatusFromDing(@RequestBody Map map, HttpServletRequest request){
        ResultEntity resultEntity = new ResultEntity();
        Object staffName = request.getAttribute("staffName");
        ProgressUtil.percent = 10;

        //用户传入的年月日信息
        Object object = map.get("month");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        //当前年月日信息
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;

        //设置当月第一天
        calendar.set(Calendar.DAY_OF_MONTH, 1);

        //获取当月一号的时间戳
        long headOfCurrentMonthTime = calendar.getTimeInMillis();

        //获取当前时间戳
        long currentTime = System.currentTimeMillis();

        try{
            calendar.setTime(sdf.parse(object.toString().substring(0,10)));
        }catch (ParseException pe){
            pe.printStackTrace();
            resultEntity.setCode("F");
            resultEntity.setMsg("月份信息有误");
            return resultEntity;
        }

        int yearSelected = calendar.get(Calendar.YEAR);
        int monthSelected = calendar.get(Calendar.MONTH) + 1;
        int totalDaysSelected = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        //获取用户传入月份的第一天的时间戳
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        long selectedFirstTime = calendar.getTimeInMillis();

        //获取用户传入月份的最后一天的时间戳
        calendar.set(Calendar.DAY_OF_MONTH, totalDaysSelected);
        long selectedLastTime = calendar.getTimeInMillis() + 86400000;


        //获取所有通讯里ID
        List<String> idList = dingAccessUtils.doGetUserIds(iContactBasicService.selectAllContactBasic());

        System.out.println("本地通讯里中包含离职的人员共有：" + idList.size());

        List<DingLeaveRecord> totalList;

        //获取考勤单据
        if(year == yearSelected){
            if(month == monthSelected){
                System.out.println("用户选择了当年当月" + "开始时间戳为：" + headOfCurrentMonthTime + " 结束时间戳为：" + currentTime);
                //当年当月的处理
                totalList = this.getDingLeaveRecordByIds(headOfCurrentMonthTime, currentTime, idList);
            }else if(monthSelected < month && (month - monthSelected) < 6){
                System.out.println("用户选择了当年小于6个月" + "开始时间戳为：" + selectedFirstTime + " 结束时间戳为：" + selectedLastTime);
                //当年小于6个月的处理
                totalList = this.getDingLeaveRecordByIds(selectedFirstTime, selectedLastTime, idList);
            }else{
                resultEntity.setCode("F");
                resultEntity.setMsg("月份信息有误");
                return resultEntity;
            }
        }else{
            if(year < yearSelected){ //选择的年份大于当前年份
                resultEntity.setCode("F");
                resultEntity.setMsg("年份信息有误");
                return resultEntity;
            }else{ //选择的年份小于当前年份，月份跨度最大为6个月
                if((year - yearSelected) == 1 && (12 - monthSelected + month) < 6){
                    System.out.println("用户选择了跨年小于6个月, " + "开始时间戳为：" + selectedFirstTime + " 结束时间戳为：" + selectedLastTime);
                    //跨年小于6个月的处理
                    totalList = this.getDingLeaveRecordByIds(selectedFirstTime, selectedLastTime, idList);
                }else{
                    resultEntity.setCode("F");
                    resultEntity.setMsg("跨度不能大于6个月");
                    return resultEntity;
                }
            }
        }

        System.out.println("一共从钉钉中查询出: " + totalList.size() + " 条考勤记录");

        ProgressUtil.percent = 30;

        //查询数据库，如果记录存在就不做任何操作，如果不存在，就执行插入操作
        int countInsert = 0;
        Date date = new Date();
        if(totalList.size() != 0){
            for (DingLeaveRecord d : totalList
                 ) {
                DingLeaveRecord record = iDingLeaveRecordService.selectOneDingLeaveRecord(d);
                if(null != record){
                    //System.out.println(record.toString());
                }
                if(null == record){
                    d.setcTime(date);
                    countInsert = countInsert + iDingLeaveRecordService.insertDingLeaveRecord(d);
                }
            }
        }

        ProgressUtil.percent = 70;

        //向数据库更新考勤规则（只增不减）
        List<DingAdminEntity> admins = dingAccessUtils.getDingAdmins();
        String adminid = null;
        for (DingAdminEntity admin : admins
             ) {
            if(admin.getSys_level() == 1){
                adminid = admin.getUserid();
            }
        }
        if(null != adminid){
            List<DingVacationType> typeList = dingAccessUtils.getDingVacationTypeList(adminid);
            for (DingVacationType dvt : typeList
                 ) {
                DingVacationType type = iDingVacationTypeService.selectOneDingVacationType(dvt);
                if(null == type){
                    dvt.setcTime(date);
                    iDingVacationTypeService.insertDingVacationType(dvt);
                }
            }
        }

        ProgressUtil.percent = 96;
        logUtil.insertSystemEventLog(staffName.toString(), new Date(), "同步了钉钉中" + month + "月份的考勤单据", "考勤");
        List<Integer> resList = new ArrayList<>();
        resList.add(countInsert);
        resultEntity.setCode("S");
        resultEntity.setDataList(resList);
        resultEntity.setMsg("同步成功");
        return resultEntity;
    }


    /**
     * 该方法主要功能是将传入的钉钉userid按照每100个进行分组循环，钉钉规定，每次最多传入100个userId
     * @param startTime 开始时间，保持不变
     * @param endTime 结束时间，保持不变
     * @param userIds 用户总的id数据集合
     * @return 返回查询到的总记录
     */
    private List<DingLeaveRecord> getDingLeaveRecordByIds(long startTime, long endTime, List<String> userIds){
        List<DingLeaveRecord> totalList = new ArrayList<>();
        int count = userIds.size() / 100; //钉钉规定，每次最多传入100个userId
        int leftIds = userIds.size() % 100;
        if(count == 0){
            totalList.addAll(dingAccessUtils.getDingLeaveRecords(startTime, endTime, userIds, 0, totalList));
        }else{
            if(leftIds == 0){
                for (int i = 0; i < count; i++) {
                    List<DingLeaveRecord> casualList = new ArrayList<>();
                    totalList.addAll(dingAccessUtils.getDingLeaveRecords(startTime, endTime, userIds.subList(i*100, (i + 1) * 100), 0, casualList));
                }
            }else{
                for (int i = 0; i <= count; i++) {
                    if(i == count){
                        //System.out.println("传入的id数组索引为：" + count*100 + " 到 " + (count*100 + leftIds));
                        List<DingLeaveRecord> casualList = new ArrayList<>();
                        totalList.addAll(dingAccessUtils.getDingLeaveRecords(startTime, endTime, userIds.subList(count*100, count*100 + leftIds), 0, casualList));
                    }else{
                        //System.out.println("传入的id数组索引为：" + i*100 + " 到 " + (i + 1) * 100);
                        List<DingLeaveRecord> casualList = new ArrayList<>();
                        totalList.addAll(dingAccessUtils.getDingLeaveRecords(startTime, endTime, userIds.subList(i*100, (i + 1) * 100), 0, casualList));
                    }
                }
            }
        }
        return totalList;
    }

    /**
     * 该方法接收前端用户指定的时间段，向数据库查询来自钉钉的考勤记录
     * @param map 时间段
     * @param request http请求
     * @return 标准返回值对象
     */
    @RequestMapping("/basic/getDingLeaveRecordsByRangeDate")
    @ResponseBody
    public ResultEntity getDingLeaveRecordsByRangeDate(@RequestBody Map map, HttpServletRequest request){
        ResultEntity resultEntity = new ResultEntity();
        if(null != map){
            Object rangeDate = map.get("rangeDate");
            try{
                JSONArray dateArray = JSON.parseArray(JSON.toJSONString(rangeDate));
                String startTime = dateArray.getString(0);
                String endTime = dateArray.getString(1);
                List<DingLeaveRecord> resultList = iDingLeaveRecordService.selectDingLeaveRecordByRangeDate(startTime, endTime);
                resultEntity.setCode("S");
                resultEntity.setMsg("Success");
                resultEntity.setDataList(resultList);
                return resultEntity;
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        resultEntity.setCode("F");
        resultEntity.setMsg("查询失败");
        return resultEntity;
    }


}
